'''
Created on Nov 27, 2019
@author: Liang.Li
'''
from library.web.client import HttpClient
from library.mgr.usrmgr import UserManager
import time,json
import os

class CAEUserManager(UserManager):
	__slots__ = ('__http', '__path_login', '__path_adduser', '__path_active', '__path_reset_passwd', '__path_change_passwd', '__path_forgot_passwd', '__url', '__token', '__path_recovery_question')
	
	def __init__(self, url='', api_token='', path_login='', path_adduser='', path_active='', path_reset_passwd='', path_change_passwd='', path_forgot_passwd='', path_recovery_question=''):
		self.__http = HttpClient(url, Authorization='SSWS %s' % api_token)
		self.__path_login = path_login
		self.__path_adduser = path_adduser
		self.__path_active = path_active
		self.__path_reset_passwd = path_reset_passwd
		self.__path_change_passwd = path_change_passwd
		self.__path_forgot_passwd = path_forgot_passwd
		self.__url = url
		self.__token = api_token
		self.__path_recovery_question = path_recovery_question
	def add(self, username, **kwargs):
		# if os.path.isfile("../cae_log.txt"):
		#     f = open("../cae_log.txt", 'a+', encoding='utf-8')
		# else:
		#     f = open("../cae_log.txt", 'w+', encoding='utf-8')
		kwargs['login'] = username
		passwd = kwargs.pop('password', '')
		question = kwargs.pop('question', '')
		answer = kwargs.pop('answer', '')
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		# f.write(str(kwargs))
		# kwargs.pop('okta')
		f.write("kwargs: " + str(kwargs))
		# f.write(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
		# f.write('data: ' + str(kwargs))
		# f.close()
		self.__http = HttpClient(self.__url, Authorization='SSWS %s' % self.__token)
		status, msg, data = self.__http.post(self.__path_adduser, {'profile': kwargs, "groupIds": ["00goeh9h14ysoSBvZ0h7"]}, {'activate': False})
		# f.write('Time: \n    ' + time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + '\n')
		# f.write("status: \n    " + str(status) + '\n')
		f.write("add user url: \n    " + self.__path_adduser + '\n')
		if status == 200:
			ID = data.get('id', '')
			f.write("active url: \n    " + self.__path_active + '\n')
			self.__http = HttpClient(self.__url, Authorization='SSWS %s' % self.__token)
			status, msg, data = self.__http.post(self.__path_active.replace('{{userId}}', ID), {}, {'sendEmail': False})
			if status == 200:
				f.write("login url: \n    " + self.__path_login + '\n')
				self.__http = HttpClient(self.__url, Authorization='SSWS %s' % self.__token)
				status, msg, data = self.__http.post(self.__path_login, {'token': data.get('activationToken', '')})
				if status == 200:
					f.write("reset passwd url: \n    " + self.__path_reset_passwd + '\n')
					self.__http = HttpClient(self.__url, Authorization='SSWS %s' % self.__token)
					status, msg, data = self.__http.post(self.__path_reset_passwd, {'stateToken': data.get('stateToken', ''), 'newPassword': passwd})
					if status == 200:
						f.write("question url: \n    " + self.__path_recovery_question + '\n')
						self.__http = HttpClient(self.__url, Authorization='SSWS %s' % self.__token)
						status, msg, data = self.__http.post(self.__path_recovery_question.replace('{{userId}}', ID), {"credentials": {"recovery_question": {"question": question,"answer": answer}
					}})
						if status == 200:
							return (True, {'okta': ID})
		f.write("status: \n    " + str(status) + '\n')
		f.write("msg: \n    " + str(msg) + '\n')
		f.write("data: \n    " + str(data) + '\n')
		f.close()
		return (False, str(data or msg))
	def login(self, username, **kwargs):
		status, msg, data = self.__http.post(self.__path_login, {
			'username': username,
			'password': kwargs.get('password', ''),
			'options': {
				'multiOptionalFactorEnroll': True,
				'warnBeforePasswordExpired': True
			}
		})
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		# f.write("status: " + str(status) + '\n')
		# f.write("data: " + str(data) + '\n')
		# f.write("_embedded: " + str(data.get('_embedded')) + '\n')
		# f.write("_embedded: " + str(data.get('_embedded').get('user')) + '\n')
		# f.write("_embedded: " + str(data.get('_embedded').get('user').get('id') + '\n')
		if status == 200:
			return (True, {'name': username, 'okta': data.get('_embedded').get('user').get('id', '')}) if data.get('status', '').upper() == 'SUCCESS' else (False, None)
		# f.write("msg: " + msg + '\n')
		f.write("status: " + str(status) + '\n')
		f.write("msg: " + str(msg) + '\n')
		f.write("data: " + str(data) + '\n')
		f.close()
		return (False, str(data or msg))
	def change_password(self, okta_id, oldpass, newpass):
		status, msg, data = self.__http.post(self.__path_change_passwd.replace('{{userId}}', okta_id), {
			'oldPassword': {'value': oldpass},
			'newPassword': {'value': newpass}
		})
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		f.write("status: " + str(status) + '\n')
		f.write("data: " + str(data) + '\n')
		f.close()
		return (True, data) if status == 200 else (False, str(data or msg))
	def forgot_password(self, username, relayState=''):
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		f.write("method name: forgot password\n")
		f.write("username: " + username + "\n")
		f.write("relayState: " + relayState + "\n")
		f.write("url: " + self.__path_forgot_passwd + "\n")
		status, msg, data = self.__http.post(self.__path_forgot_passwd, {
			'username': username,
			'relayState': relayState 
		})
		# logData = {
		# 	"method name": "forgot password",
		# 	"username": username,
		# 	"relayState": relayState,
		# 	"url": self.__path_forgot_passwd,
		# 	"status": str(status),
		# 	"data": str(data),
		# 	"msg": str(msg)
		# }
		# caeLog.writeLog(kwargs=json.dumps(logData))
		f.write("status: " + str(status) + "\n")
		f.write("data: " + str(data) + "\n")
		f.write("msg: " + str(msg) + "\n")
		f.close()
		return (True, str(data)) if status == 200 else (False, str(data or msg))
	def forgot_password_recovery_token(self, token=''):
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		f.write("method name: forgot password recovery token\n")
		f.write("token: " + token + '\n')
		status, msg, data = self.__http.post("/api/v1/authn/recovery/token", {
			'recoveryToken': token
		})
		f.write("status: " + str(status) + "\n")
		f.write("data: " + str(data) + "\n")
		f.write("msg: " + str(msg) + "\n")
		f.close()
		return (True, data) if status == 200 else (False, str(data or msg))
	def forgot_password_new_pwd(self, token='', newPWD=''):
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		f.write("method name: forgot password new pwd\n")
		f.write("token: " + token + '\n')
		status, msg, data = self.__http.post("/api/v1/authn/credentials/reset_password", {
			'stateToken': token,
			"newPassword": newPWD
		})
		f.write("status: " + str(status) + "\n")
		f.write("data: " + str(data) + "\n")
		f.write("msg: " + str(msg) + "\n")
		f.close()
		return (True, data) if status == 200 else (False, str(data or msg))
	def forgot_password_ques(self, token='', answer=''):
		f = open("../cae_log.txt", 'w+', encoding='utf-8')
		f.write("method name: forgot password question\n")
		f.write("token: " + token + '\n')
		f.write("answer: " + answer + '\n')
		status, msg, data = self.__http.post("/api/v1/authn/recovery/answer", {
			'stateToken': token,
			"answer": answer
		})
		f.write("status: " + str(status) + "\n")
		f.write("data: " + str(data) + "\n")
		f.write("msg: " + str(msg) + "\n")
		f.close()
		return (True, data) if status == 200 else (False, str(data or msg))
	def register(self, username, **kwargs):
		return self.add(username, **kwargs)
	def recovery_question(self, okta_id, question='', answer=''):
		status, msg, data = self.__http.post(self.__path_recovery_question.replace('{{userId}}', okta_id), {
			"credentials": {
				"recovery_question": {
					"question": question,
					"answer": answer
				}
			}
		})
		logData = {
			'okta_id': okta_id,
			'question': question,
			'answer': answer,
			"url": self.__path_recovery_question,
			"status": str(status),
			"data": str(data),
			"msg": str(msg)
		}
		caeLog.writeLog(kwargs=json.dumps(logData))
		return (True, data) if status == 200 else (False, str(data or msg))

class caeLog():
	@classmethod
	def writeLog(cls, openType='w+', kwargs=''):
		param = json.loads(kwargs)
		f = open("../cae_log.txt", openType, encoding='utf-8')
		for k in param.keys():
			f.write(k + ": " + str(param[k]) + "\n")
		f.close()
